import java.util.Random;
import java.util.concurrent.*;

public class ThreadFutureDemo {
    public static void main(String[] args) throws InterruptedException {
        ExecutorService executorService = Executors.newFixedThreadPool(3);

        Future<Boolean> future1 = executorService.submit(new CallableRandomTime(100));
        Future<Boolean> future2 = executorService.submit(new CallableRandomTime(200));
        Future<Boolean> future3 = executorService.submit(new CallableRandomTime(300));
        Future<Boolean> future4 = executorService.submit(new CallableRandomTime(400));
        Future<Boolean> future5 = executorService.submit(new CallableRandomTime(500));
        try {
            System.out.println("future 1 done : " + future1.get(30,TimeUnit.SECONDS));
            System.out.println("future 2 done : " + future2.get(30,TimeUnit.SECONDS));
            System.out.println("future 3 done : " + future3.get(30,TimeUnit.SECONDS));
            System.out.println("future 4 done : " + future4.get(30,TimeUnit.SECONDS));
            System.out.println("future 5 done : " + future5.get(30,TimeUnit.SECONDS));
            System.out.println("------------ done ! -------------");
        } catch (ExecutionException | TimeoutException e) {
            throw new RuntimeException(e);
        }
        executorService.shutdown();
    }

    private static class CallableRandomTime implements Callable<Boolean> {
        private Integer bound = 100;

        private CallableRandomTime(Integer bound) {
            this.bound = bound;
        }

        @Override
        public Boolean call() throws Exception {
            Thread.currentThread().setName("thread"+bound);
            Random random = new Random();
            for (int i = 0; i < 5; i++) {
                int r = random.nextInt(bound);
                System.out.println(Thread.currentThread().getName() + " random num "+ i +" : " + r);
                Thread.sleep(r * 10L);
            }
            return true;
        }
    }

}
